package post

import (
	"context"
	"regexp"
	"strings"

	"mall/common/enumx"
	"mall/common/modelx"
	"mall/common/resultx"
	"mall/common/sqrlx"
	"mall/service/blog/model"
	"mall/service/blog/rpc/internal/svc"
	"mall/service/blog/rpc/types/blog"

	"github.com/zeromicro/go-zero/core/logx"
)

type PostListLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewPostListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PostListLogic {
	return &PostListLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *PostListLogic) PostList(in *blog.PostListReq) (*blog.PostListResp, error) {
	if in.Preload == "" && in.EagerLoad == "" {
		return nil, resultx.StatusError(resultx.REUQEST_PARAM_ERROR, "")
	}

	logx.Infof("PostListReq: %+v ", in)
	// Preload:\"blogPost:Title,Slug,Uri;blogMedia:altText,sourceUrl,mediaDetails;blogPostMeta:fullHead,title,metaDesc\"  EagerLoad:\"blogPost:blogMedia,blogPostMeta\"
	// Preload:\"blogPost:Title,Slug,Uri\" PreFilterEntity:\"blogTerm\" PreFilter:\"name,equalTo:uncategorized\"

	preloadMap, eagerLoadMap := modelx.GetPreloadMap(in.Preload, in.EagerLoad)
	logx.Infof("preloadMap: %+v ", preloadMap)
	// preloadMap: map[blogPost:[Uri]]
	logx.Infof("eagerLoadMap: %+v ", eagerLoadMap)
	// eagerLoadMap:

	blogPostEntityName := model.RpcEntityNames.BlogPost
	_, hasEntitySettings := model.RpcEntityPreloadMap[blogPostEntityName] // BlogPost的关联字段
	if !hasEntitySettings {
		return &blog.PostListResp{}, nil
	}

	blogPostRepositoryName := model.RepositoryNames.BlogPost
	columnMap, hasColumnMap := model.RepositoryPreloadMap[blogPostRepositoryName] // BlogPost的数据库字段
	if !hasColumnMap {
		return &blog.PostListResp{}, nil
	}

	var selectCols []string
	if preloadFields, hasPreloadFields := preloadMap[blogPostEntityName]; hasPreloadFields {
		selectColMap := make(map[string]string)
		for _, field := range preloadFields {
			if _, exist := selectColMap[field]; !exist {
				if column, hasColumn := columnMap[field]; hasColumn {
					selectColMap[field] = column
				} else {
					selectColMap[field] = ""
				}
			}
		}
		for _, column := range selectColMap {
			if column != "" {
				selectCols = append(selectCols, column)
			}
		}
	}

	var count int64
	var oids []any // []model.BlogTermRelationship.ObjectID(已去重)
	var preFilter bool
	if in.PreFilterEntity != "" && in.PreFilter != "" {
		preFilter = true
		blogTermRpcEntityName := model.RpcEntityNames.BlogTerm
		blogTermRepositoryName := model.RepositoryNames.BlogTerm
		if blogTermRpcEntityName == in.PreFilterEntity {
			_, hasRpcEntitySettingMap := model.RpcEntityPreloadMap[blogTermRpcEntityName]
			preColumnMap, hasPreColumnMap := model.RepositoryPreloadMap[blogTermRepositoryName]
			if hasRpcEntitySettingMap && hasPreColumnMap {
				var preFilterMap map[string]map[string][]any
				preFilterMap = modelx.GetFilterMap(in.PreFilter, preColumnMap)
				logx.Infof("preFilterMap: %+v ", preFilterMap)
				// preFilterMap:
				var pageSize int64 = 1
				termList, _, err := l.svcCtx.BlogTerm.GetList(l.ctx, model.M{
					"pageSize": pageSize,
					"select":   ",",
				}, -1, preFilterMap)
				if err != nil {
					return nil, err
				}
				if len(termList) > 0 {
					subPreFilterMap := modelx.GetFilterMap(in.Filter, preColumnMap)
					if subPreFilterMap == nil {
						subPreFilterMap = make(map[string]map[string][]any)
					}
					subPreFilterMap[model.BlogTermRelationshipColumns.TermID] = map[string][]any{
						"equalTo": []any{termList[0].TermID},
					}
					subPreFilterMap[model.BlogTermRelationshipColumns.ObjectType] = map[string][]any{
						"equalTo": []any{enumx.PostTypePost},
					}
					orderBy := modelx.GetOrderBy(in.PreSorter, preColumnMap)
					logx.Infof("preOrderBy: %s ", orderBy)
					logx.Infof("subPreFilterMap: %+v ", subPreFilterMap)
					relationshipList, preCount, err := l.svcCtx.BlogTerm.GetRelationshipList(l.ctx, model.M{
						"offset":  in.Offset,
						"limit":   in.Limit,
						"orderBy": orderBy,
						"select":  model.BlogTermRelationshipColumns.ObjectID,
					}, 2, subPreFilterMap)
					if err != nil {
						return nil, err
					}
					count = preCount
					if len(relationshipList) > 0 {
						oidMap := make(map[uint64]int) // Map: model.BlogTermRelationship.ObjectID => int
						for i, relationship := range relationshipList {
							if _, exist := oidMap[relationship.ObjectID]; !exist {
								oids = append(oids, relationship.ObjectID)
								oidMap[relationship.ObjectID] = i
							}
						}
					}
				}
			}
		}
	}

	var filterMap map[string]map[string][]any
	if in.Filter != "" {
		filterMap = modelx.GetFilterMap(in.Filter, columnMap)
		logx.Infof("filterMap: %+v ", filterMap)
		// filterMap:
	}
	if filterMap == nil {
		filterMap = make(map[string]map[string][]any)
		filterMap[model.BlogKnowledgeBasisColumns.PostStatus] = map[string][]any{
			"equalTo": []any{enumx.PostStatusPublish},
		}
	}

	var postList []*model.BlogPost
	var err error
	if preFilter {
		if len(oids) > 0 {
			filterMap[model.BlogPostColumns.ID] = map[string][]any{
				"in": oids,
			}
			tmpList, _, tmpErr := l.svcCtx.BlogPost.GetList(l.ctx, model.M{
				"select": strings.Join(selectCols, ","),
			}, -1, filterMap)
			if tmpErr != nil {
				return nil, tmpErr
			}
			tmpMap := make(map[any]*model.BlogPost)
			for _, tmp := range tmpList {
				tmpMap[tmp.ID] = tmp
			}
			for _, oid := range oids {
				if tmp, exist := tmpMap[oid]; exist {
					postList = append(postList, tmp)
				}
			}
		}
	} else {
		postList, count, err = l.svcCtx.BlogPost.GetList(l.ctx, model.M{
			"offset": in.Offset,
			"limit":  in.Limit,
			"select": strings.Join(selectCols, ","),
		}, 2, filterMap)
		if err != nil {
			return nil, err
		}
	}

	var posts []*blog.PostDetailResponse
	if len(postList) > 0 {
		var ids []any // []model.BlogPost.ID
		for _, post := range postList {
			ids = append(ids, post.ID)
		}

		subRpcEntitySettingMap := make(map[string]map[string]*model.ColumnSetting)
		if eagerLoadRpcEntities, hasEagerLoadRpcEntities := eagerLoadMap[blogPostEntityName]; hasEagerLoadRpcEntities {
			for _, entity := range eagerLoadRpcEntities {
				if rpcEntitySettingMap, hasRpcEntitySettingMap := model.RpcEntityPreloadMap[entity]; hasRpcEntitySettingMap {
					subRpcEntitySettingMap[entity] = rpcEntitySettingMap
				}
			}
		}

		idCategoryMap := make(map[uint64][]*blog.BlogCategory) // Map: model.BlogPost.ID => []*blog.BlogCategory
		idTagMap := make(map[uint64][]*blog.BlogTag)           // Map: model.BlogPost.ID => []*blog.BlogTag
		blogTermRpcEntityName := model.RpcEntityNames.BlogTerm
		blogTermRepositoryName := model.RepositoryNames.BlogTerm
		if _, hasRpcEntitySettingMap := subRpcEntitySettingMap[blogTermRpcEntityName]; hasRpcEntitySettingMap {
			preloadFields, hasPreloadFields := preloadMap[blogTermRpcEntityName]
			subColumnMap, hasSubColumnMap := model.RepositoryPreloadMap[blogTermRepositoryName]
			if hasPreloadFields && hasSubColumnMap {
				subFilterMap := make(map[string]map[string][]any)
				subFilterMap[model.BlogTermRelationshipColumns.ObjectID] = map[string][]any{
					"in": ids,
				}
				subFilterMap[model.BlogTermRelationshipColumns.ObjectType] = map[string][]any{
					"equalTo": []any{enumx.PostTypePost},
				}
				relationshipList, _, err := l.svcCtx.BlogTerm.GetRelationshipList(l.ctx, model.M{}, -1, subFilterMap)
				if err != nil {
					return nil, err
				}
				if len(relationshipList) > 0 {
					selectColMap := make(map[string]string)
					for _, field := range preloadFields {
						if _, exist := selectColMap[field]; !exist {
							if column, hasColumn := subColumnMap[field]; hasColumn {
								selectColMap[field] = column
							} else {
								selectColMap[field] = ""
							}
						}
					}
					var subSelectCols []string
					for _, column := range selectColMap {
						if column != "" {
							subSelectCols = append(subSelectCols, column)
						}
					}

					tidMap := make(map[uint64][]uint64) // Map: model.BlogTerm.TermID => []model.BlogPost.ID
					var tids []any              // []model.BlogTerm.TermID(已去重)
					for _, relationship := range relationshipList {
						if _, exist := tidMap[relationship.TermID]; !exist {
							tids = append(tids, relationship.TermID)
						}
						tidMap[relationship.TermID] = append(tidMap[relationship.TermID], relationship.ObjectID)
					}

					termFilterMap := make(map[string]map[string][]any)
					termFilterMap[model.BlogTermColumns.TermID] = map[string][]any{
						"in": tids,
					}
					termList, _, err := l.svcCtx.BlogTerm.GetList(l.ctx, model.M{
						"select": strings.Join(subSelectCols, ","),
					}, -1, termFilterMap)
					if err != nil {
						return nil, err
					}
					if len(termList) > 0 {
						for _, term := range termList {
							if oids, exist := tidMap[term.TermID]; exist {
								if term.Taxonomy == uint16(enumx.TermTaxonomyCategory) { // 是分类
									oidMap := make(map[uint64]struct{})
									for _, oid := range oids {
										if _, ok := oidMap[oid]; !ok {
											idCategoryMap[oid] = append(idCategoryMap[oid], &blog.BlogCategory{
												Id:   int64(term.TermID),
												Name: term.Name,
												Slug: term.Slug,
											})
											oidMap[oid] = struct{}{}
										}
									}
								} else if term.Taxonomy == uint16(enumx.TermTaxonomyTag) { // 是标签
									oidMap := make(map[uint64]struct{})
									for _, oid := range oids {
										if _, ok := oidMap[oid]; !ok {
											idTagMap[oid] = append(idTagMap[oid], &blog.BlogTag{
												Id:   int64(term.TermID),
												Name: term.Name,
												Slug: term.Slug,
											})
											oidMap[oid] = struct{}{}
										}
									}
								}
							}
						}
					}
				}
			}
		}

		idMediaMap := make(map[uint64]*blog.BlogMedia) // Map: model.BlogPost.ID => *blog.BlogMedia
		blogMediaRpcEntityName := model.RpcEntityNames.BlogMedia
		blogMediaRepositoryName := model.RepositoryNames.BlogMedia
		if _, hasRpcEntitySettingMap := subRpcEntitySettingMap[blogMediaRpcEntityName]; hasRpcEntitySettingMap {
			preloadFields, hasPreloadFields := preloadMap[blogMediaRpcEntityName]
			subColumnMap, hasSubColumnMap := model.RepositoryPreloadMap[blogMediaRepositoryName]
			if hasPreloadFields && hasSubColumnMap {
				selectColMap := make(map[string]string)
				for _, field := range preloadFields {
					if _, exist := selectColMap[field]; !exist {
						if column, hasColumn := subColumnMap[field]; hasColumn {
							selectColMap[field] = column
						} else {
							selectColMap[field] = ""
						}
					}
				}
				var subSelectCols []string
				for _, column := range selectColMap {
					if column != "" {
						subSelectCols = append(subSelectCols, column)
					}
				}
				mediaFilterMap := make(map[string]map[string][]any)
				mediaFilterMap[model.BlogAttachmentRelationshipColumns.ObjectID] = map[string][]any{
					"in": ids,
				}
				mediaFilterMap[model.BlogAttachmentRelationshipColumns.ObjectType] = map[string][]any{
					"equalTo": []any{enumx.PostTypePost},
				}
				mediaFilterMap[model.BlogAttachmentRelationshipColumns.AttachmentThumbnail] = map[string][]any{
					"equalTo": []any{1},
				}
				mediaList, _, err := l.svcCtx.BlogPost.GetMedia(l.ctx, model.M{
					"orderBy": model.BlogAttachmentRelationshipColumns.AttachmentOrder,
					"select":  strings.Join(subSelectCols, ","),
				}, -1, mediaFilterMap) // 读取关联表
				if err != nil {
					return nil, err
				}
				if len(mediaList) > 0 {
					for _, media := range mediaList {
						if _, exist := idMediaMap[media.ObjectID]; !exist {
							idMediaMap[media.ObjectID] = &blog.BlogMedia{
								Uid:       int64(media.AttachmentRelationshipID),
								Id:        int64(media.AttachmentID),
								Uri:       media.AttachmentSource,
								Thumbnail: int32(media.AttachmentThumbnail),
								Order:     int32(media.AttachmentOrder),
								Url:       media.AttachmentImageURL,
								AltText:   media.AttachmentImageAlt,
								Meta:      media.AttachmentImageMeta,
							}
						}
					}
				}
			}
		}

		idMetaMap := make(map[uint64]*blog.BlogMeta) // Map: model.BlogPost.ID => *blog.BlogMedia
		blogPostMetaRpcEntityName := model.RpcEntityNames.BlogPostMeta
		if rpcEntitySettingMap, hasRpcEntitySettingMap := subRpcEntitySettingMap[blogPostMetaRpcEntityName]; hasRpcEntitySettingMap {
			if preloadFields, hasPreloadFields := preloadMap[blogPostMetaRpcEntityName]; hasPreloadFields {
				var metaKeys []any
				for _, field := range preloadFields {
					fieldSetting, hasFieldSetting := rpcEntitySettingMap[field]
					if hasFieldSetting && fieldSetting.Name != "" {
						metaKeys = append(metaKeys, fieldSetting.Name)
					}
				}
				if len(metaKeys) > 0 {
					metaFilterMap := make(map[string]map[string][]any)
					metaFilterMap[model.BlogPostMetumColumns.PostID] = map[string][]any{
						"in": ids,
					}
					metaFilterMap[model.BlogPostMetumColumns.MetaKey] = map[string][]any{
						"in": metaKeys,
					}
					metaList, _, err := l.svcCtx.BlogPost.GetMeta(l.ctx, model.M{}, -1, metaFilterMap)
					if err != nil {
						return nil, err
					}
					if len(metaList) > 0 {
						for _, metum := range metaList {
							if _, exist := idMetaMap[metum.PostID]; !exist {
								idMetaMap[metum.PostID] = &blog.BlogMeta{
									Id:    int64(metum.MetaID),
									Key:   metum.MetaKey,
									Value: metum.MetaValue.String,
								}
							}
						}
					}
				}
			}
		}

		for _, post := range postList {
			var categories []*blog.BlogCategory
			if terms, exist := idCategoryMap[post.ID]; exist {
				categories = terms[:]
			}
			var tags []*blog.BlogTag
			if terms, exist := idTagMap[post.ID]; exist {
				tags = terms[:]
			}
			var media []*blog.BlogMedia
			if m, exist := idMediaMap[post.ID]; exist {
				media = append(media, m)
			}
			uri := post.PostDateGMT.Format("2006/01/02/") + post.PostName
			posts = append(posts, &blog.PostDetailResponse{
				Id:            int64(post.ID),
				AuthorId:      int64(post.PostAuthorID),
				ParentId:      int64(post.PostParentID),
				Title:         post.PostTitle,
				Excerpt:       post.PostExcerpt,
				Status:        int32(post.PostStatus),
				CommentStatus: int32(post.CommentStatus),
				Slug:          post.PostName,
				Uri:           uri,
				Link:          post.GUID,
				Date:          modelx.FormatTime(post.PostDate, ""),
				DateGmt:       modelx.FormatTime(post.PostDateGMT, ""),
				Modified:      modelx.FormatTime(post.PostModifiedDate, ""),
				ModifiedGmt:   modelx.FormatTime(post.PostModifiedGMT, ""),
				CommentCount:  int32(post.CommentCount),
				Media:         media,
				Categories:    categories,
				Tags:          tags,
			})
		}
	}

	var hasNextPage int32
	var hasPreviousPage int32
	if count > 1 {
		hasNextPage = 1
		count = count - 2
	}
	if count > 0 {
		hasPreviousPage = 1
	}
	return &blog.PostListResp{
		Data:            posts,
		HasNextPage:     hasNextPage,
		HasPreviousPage: hasPreviousPage,
	}, nil
}

func (l *PostListLogic) GetTermIds(in *blog.TermListRequest) ([]int64, error) { /////
	// q := l.svcCtx.BlogTermModel.RowBuilder("t.`term_id`", "t")
	// q = q.OrderBy("t.`term_id` ASC")

	// var (
	// 	requireTaxonomy      bool
	// 	requireRelationships bool
	// )

	// if in.Name != "" {
	// 	q = q.Where(sq.Eq{"t.`name`": in.Name})
	// } else if in.NameIn != nil && len(in.NameIn) > 0 {
	// 	q = q.Where(sq.Eq{"t.`name`": in.NameIn})
	// } else if in.NameNotIn != nil && len(in.NameNotIn) > 0 {
	// 	q = q.Where(sq.NotEq{"t.`name`": in.NameNotIn})
	// }

	// if in.ObjectId > 0 {
	// 	requireRelationships = true
	// 	q = q.Where(sq.Eq{"tr.`object_id`": in.ObjectId})
	// } else if in.ObjectIdIn != nil && len(in.ObjectIdIn) > 0 {
	// 	requireRelationships = true
	// 	q = q.Where(sq.Eq{"tr.`object_id`": in.ObjectIdIn})
	// } else if in.ObjectIdNotIn != nil && len(in.ObjectIdNotIn) > 0 {
	// 	requireRelationships = true
	// 	q = q.Where(sq.NotEq{"tr.`object_id`": in.ObjectIdNotIn})
	// }

	// if in.ObjectType > 0 {
	// 	requireRelationships = true
	// 	q = q.Where(sq.NotEq{"tr.`object_type`": in.ObjectType})
	// }

	// if in.ParentId > 0 {
	// 	requireTaxonomy = true
	// 	q = q.Where(sq.Eq{"tt.`parent_id`": in.ParentId})
	// } else if in.ParentIdIn != nil && len(in.ParentIdIn) > 0 {
	// 	requireTaxonomy = true
	// 	q = q.Where(sq.Eq{"tt.`parent_id`": in.ParentIdIn})
	// } else if in.ParentIdNotIn != nil && len(in.ParentIdNotIn) > 0 {
	// 	requireTaxonomy = true
	// 	q = q.Where(sq.NotEq{"tt.`parent_id`": in.ParentIdNotIn})
	// }

	// if in.Slug != "" {
	// 	q = q.Where(sq.Eq{"t.`slug`": in.Slug})
	// } else if in.SlugIn != nil && len(in.SlugIn) > 0 {
	// 	q = q.Where(sq.Eq{"t.`slug`": in.SlugIn})
	// } else if in.SlugNotIn != nil && len(in.SlugNotIn) > 0 {
	// 	q = q.Where(sq.NotEq{"t.`slug`": in.SlugNotIn})
	// }

	// if in.Taxonomy != "" {
	// 	requireTaxonomy = true
	// 	q = q.Where(sq.Eq{"tt.`taxonomy`": in.Taxonomy})
	// } else if in.TaxonomyIn != nil && len(in.TaxonomyIn) > 0 {
	// 	requireTaxonomy = true
	// 	q = q.Where(sq.Eq{"tt.`taxonomy`": in.TaxonomyIn})
	// } else if in.TaxonomyNotIn != nil && len(in.TaxonomyNotIn) > 0 {
	// 	requireTaxonomy = true
	// 	q = q.Where(sq.NotEq{"tt.`taxonomy`": in.TaxonomyNotIn})
	// }

	// if in.Id > 0 {
	// 	q = q.Where(sq.Eq{"t.`term_id`": in.Id})
	// } else if in.IdIn != nil && len(in.IdIn) > 0 {
	// 	q = q.Where(sq.Eq{"t.`term_id`": in.IdIn})
	// } else if in.IdNotIn != nil && len(in.IdNotIn) > 0 {
	// 	q = q.Where(sq.NotEq{"t.`term_id`": in.IdNotIn})
	// }

	// if in.Offset > 0 {
	// 	q = q.Where("t.`term_id` > ?", in.Offset)
	// }

	// if in.Limit == 0 {
	// 	in.Limit = l.svcCtx.Config.Query.DefaultAmount
	// }

	// if in.Limit >= 0 {
	// 	q = q.Limit(uint64(in.Limit))
	// }

	// return l.svcCtx.BlogTermModel.QueryIds(l.ctx, q, requireTaxonomy, requireRelationships)
	return nil, nil
}

// getCategoryIdBySlug returns the id of the category that matches the given slug
func (l *PostListLogic) getCategoryIdBySlug(slug string, objectType int64) (int64, error) { /////
	slug = strings.TrimSpace(slug)
	if len(slug) == 0 {
		return 0, nil
	}

	parts := strings.Split(slug, "/") // 有 “/”，会先切割然后逐级核对，取最后一级分类的ID

	var categoryId int64
	for _, part := range parts {
		termIds, err := l.GetTermIds(&blog.TermListRequest{
			ObjectType: objectType,
			ParentId:   categoryId,
			Slug:       part,
			Taxonomy:   string(enumx.TaxonomyCategory),
		})

		if err != nil {
			return 0, err
		}

		if len(termIds) > 0 {
			categoryId = termIds[0]
		} else {
			return 0, nil
		}
	}

	return categoryId, nil
}

func (l *PostListLogic) GetChildrenIdsById(termId int64) ([]int64, error) { /////
	resp := []int64{termId}

	// ids := resp[:]
	// for len(ids) > 0 {
	// 	ids, err := l.svcCtx.BlogTermTaxonomyModel.GetChildrenIds(l.ctx, ids)
	// 	if err != nil {
	// 		break
	// 	}

	// 	resp = append(resp, ids...)
	// }

	return resp, nil
}

func (l *PostListLogic) parseCategoryFilter(in *blog.TermListRequest) { /////
	if in.Name != "" {
		var regexpCategoryNameSeparators = regexp.MustCompile("[,+~]")

		parseCategoryName := func(name string) {
			if name != "" {
				switch name[:1] {
				case "+":
					in.NameAnd = append(in.NameAnd, name[1:])
				case "~":
					in.NameNotIn = append(in.NameNotIn, name[1:])
				default:
					if name[:1] == "," {
						name = name[1:]
					}

					in.NameIn = append(in.NameIn, name)
				}
			}
		}

		prevIndex := 0
		for _, indices := range regexpCategoryNameSeparators.FindAllStringIndex(in.Name, -1) {
			parseCategoryName(in.Name[prevIndex:indices[0]])
			prevIndex = indices[0] // indices 包含start和length
		}
		parseCategoryName(in.Name[prevIndex:])

		in.Name = ""
	}

	if in.NameAnd != nil && len(in.NameAnd) > 0 {
		for _, name := range sqrlx.UniqueString(in.NameAnd) {
			catId, _ := l.getCategoryIdBySlug(name, in.ObjectType)
			if catId == 0 {
				continue
			}

			in.IdAnd = append(in.IdAnd, catId)
		}
	} else if in.NameIn != nil && len(in.NameIn) > 0 {
		for _, name := range sqrlx.UniqueString(in.NameIn) {
			catId, _ := l.getCategoryIdBySlug(name, in.ObjectType)
			if catId == 0 {
				continue
			}

			in.IdIn = append(in.IdIn, catId)
		}
	} else if in.NameNotIn != nil && len(in.NameNotIn) > 0 {
		for _, name := range sqrlx.UniqueString(in.NameNotIn) {
			catId, _ := l.getCategoryIdBySlug(name, in.ObjectType)
			if catId == 0 {
				continue
			}

			in.IdNotIn = append(in.IdNotIn, catId)
		}
	}
}

//// FilterList returns the ids of the posts that match the request
// func (l *PostListLogic) FilterList(in *blog.ObjectListRequest) ([]int64, error) {
// var q sq.SelectBuilder
// var termsSubQuery sq.SelectBuilder
// var userSubQuery sq.SelectBuilder
// var regexpQueryDelimiter = regexp.MustCompile("[^a-zA-Z]")

// q = l.svcCtx.BlogPostModel.RowBuilder("ID", "")
// termsSubQuery = l.svcCtx.BlogTermModel.SubQueryBuilder(in.ObjectType)
// userSubQuery = l.svcCtx.BlogUserModel.RowBuilder("", "")

// if in.PostStatus > 0 {
// 	q = q.Where(sq.Eq{"post_status": in.PostStatus})
// } else if in.PostStatusIn != nil && len(in.PostStatusIn) > 0 {
// 	q = q.Where(sq.Eq{"post_status": in.PostStatusIn})
// }

// if in.AuthorId > 0 {
// 	q = q.Where(sq.Eq{"post_author_id": in.AuthorId})
// } else if in.AuthorIn != nil && len(in.AuthorIn) > 0 {
// 	q = q.Where(sq.Eq{"post_author_id": in.AuthorIn})
// } else if in.AuthorNotIn != nil && len(in.AuthorNotIn) > 0 {
// 	q = q.Where(sq.NotEq{"post_author_id": in.AuthorNotIn})
// }

// if in.AuthorName != "" {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "post_author_id",
// 		Query:  userSubQuery.Where(sq.Eq{"user_nicename": in.AuthorName}),
// 	})
// } else if in.AuthorNameIn != nil && len(in.AuthorNameIn) > 0 {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "post_author_id",
// 		Query:  userSubQuery.Where(sq.Eq{"user_nicename": in.AuthorNameIn}),
// 	})
// } else if in.AuthorNameNotIn != nil && len(in.AuthorNameNotIn) > 0 {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "post_author_id",
// 		Query:  userSubQuery.Where(sq.Eq{"user_nicename": in.AuthorNameNotIn}),
// 		Neg:    true,
// 	})
// }

// if in.CategoryFilter != nil {
// 	l.parseCategoryFilter(in.CategoryFilter)

// 	if in.CategoryFilter.Id > 0 {
// 		ids, err := l.GetChildrenIdsById(in.CategoryFilter.Id)
// 		if err != nil {
// 			return nil, err
// 		}

// 		q = q.Where(sqrlx.InSubquery{
// 			Column: "ID",
// 			Query: termsSubQuery.Where(sq.Eq{
// 				"tt.`taxonomy`": string(enumx.TaxonomyCategory),
// 				"t.`term_id`":   ids,
// 			}),
// 		})
// 	} else if in.CategoryFilter.IdAnd != nil && len(in.CategoryFilter.IdAnd) > 0 {
// 		for _, categoryId := range sqrlx.UniqueInt64(in.CategoryFilter.IdAnd) {
// 			ids, err := l.GetChildrenIdsById(categoryId)
// 			if err != nil {
// 				return nil, err
// 			}

// 			q = q.Where(sqrlx.InSubquery{
// 				Column: "ID",
// 				Query: termsSubQuery.Where(sq.Eq{
// 					"tt.`taxonomy`": string(enumx.TaxonomyCategory),
// 					"t.`term_id`":   ids,
// 				}),
// 			})
// 		}
// 	} else if in.CategoryFilter.IdIn != nil && len(in.CategoryFilter.IdIn) > 0 {
// 		var catIds []int64
// 		for _, categoryId := range sqrlx.UniqueInt64(in.CategoryFilter.IdIn) {
// 			ids, err := l.GetChildrenIdsById(categoryId)
// 			if err != nil {
// 				return nil, err
// 			}

// 			catIds = append(catIds, ids...)
// 		}

// 		q = q.Where(sqrlx.InSubquery{
// 			Column: "ID",
// 			Query: termsSubQuery.Where(sq.Eq{
// 				"tt.`taxonomy`": string(enumx.TaxonomyCategory),
// 				"t.`term_id`":   sqrlx.UniqueInt64(catIds),
// 			}),
// 		})
// 	} else if in.CategoryFilter.IdNotIn != nil && len(in.CategoryFilter.IdNotIn) > 0 {
// 		var catIds []int64
// 		for _, categoryId := range sqrlx.UniqueInt64(in.CategoryFilter.IdNotIn) {
// 			ids, err := l.GetChildrenIdsById(categoryId)
// 			if err != nil {
// 				return nil, err
// 			}

// 			catIds = append(catIds, ids...)
// 		}

// 		q = q.Where(sqrlx.InSubquery{
// 			Column: "ID",
// 			Query: termsSubQuery.Where(sq.Eq{
// 				"tt.`taxonomy`": string(enumx.TaxonomyCategory),
// 				"t.`term_id`":   sqrlx.UniqueInt64(catIds),
// 			}),
// 			Neg: true,
// 		})
// 	}
// }

// if in.MenuId > 0 {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "ID",
// 		Query: termsSubQuery.Where(sq.Eq{
// 			"tt.`taxonomy`": string(enumx.TaxonomyNavMenu),
// 			"t.`term_id`":   in.MenuId,
// 		}),
// 	})
// } else if in.MenuIdAnd != nil && len(in.MenuIdAnd) > 0 {
// 	for _, menuId := range sqrlx.UniqueInt64(in.MenuIdAnd) {
// 		q = q.Where(sqrlx.InSubquery{
// 			Column: "ID",
// 			Query: termsSubQuery.Where(sq.Eq{
// 				"tt.`taxonomy`": string(enumx.TaxonomyNavMenu),
// 				"t.`term_id`":   menuId,
// 			}),
// 		})
// 	}
// } else if in.MenuIdIn != nil && len(in.MenuIdIn) > 0 {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "ID",
// 		Query: termsSubQuery.Where(sq.Eq{
// 			"tt.`taxonomy`": string(enumx.TaxonomyNavMenu),
// 			"t.`term_id`":   sqrlx.UniqueInt64(in.MenuIdIn),
// 		}),
// 	})
// } else if in.MenuIdNotIn != nil && len(in.MenuIdNotIn) > 0 {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "ID",
// 		Query: termsSubQuery.Where(sq.Eq{
// 			"tt.`taxonomy`": string(enumx.TaxonomyNavMenu),
// 			"t.`term_id`":   sqrlx.UniqueInt64(in.MenuIdNotIn),
// 		}),
// 		Neg: true,
// 	})
// }

// if in.MenuName != "" {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "ID",
// 		Query: termsSubQuery.Where(sq.Eq{
// 			"tt.`taxonomy`": string(enumx.TaxonomyNavMenu),
// 			"t.`slug`":      in.MenuName,
// 		}),
// 	})
// } else if in.MenuNameAnd != nil && len(in.MenuNameAnd) > 0 {
// 	for _, name := range sqrlx.UniqueString(in.MenuNameAnd) {
// 		q = q.Where(sqrlx.InSubquery{
// 			Column: "ID",
// 			Query: termsSubQuery.Where(sq.Eq{
// 				"tt.`taxonomy`": string(enumx.TaxonomyNavMenu),
// 				"t.`slug`":      name,
// 			}),
// 		})
// 	}
// } else if in.MenuNameIn != nil && len(in.MenuNameIn) > 0 {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "ID",
// 		Query: termsSubQuery.Where(sq.Eq{
// 			"tt.`taxonomy`": string(enumx.TaxonomyNavMenu),
// 			"t.`slug`":      sqrlx.UniqueString(in.MenuNameIn),
// 		}),
// 	})
// } else if in.MenuNameNotIn != nil && len(in.MenuNameNotIn) > 0 {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "ID",
// 		Query: termsSubQuery.Where(sq.Eq{
// 			"tt.`taxonomy`": string(enumx.TaxonomyNavMenu),
// 			"t.`slug`":      sqrlx.UniqueString(in.MenuNameNotIn),
// 		}),
// 		Neg: true,
// 	})
// }

// var searchMeta = func(metas ...string) { // 按照meta_key（有'='，同时按照meta_value）查询
// 	neg := false
// 	if metas[0] == "is not in" {
// 		neg = true
// 		metas = metas[1:]
// 	}

// 	if len(metas) == 0 {
// 		return
// 	}

// 	var subQuery sq.SelectBuilder
// 	subQuery = l.svcCtx.BlogPostMetaModel.RowBuilder("", "")
// 	subQuery = subQuery.Distinct()

// 	var metaConds sq.Or
// 	for _, meta := range metas {
// 		metaCond := make(sq.Eq)
// 		if equal := strings.IndexRune(meta, '='); equal != -1 {
// 			metaCond["meta_value"] = meta[equal+1:]
// 			meta = meta[:equal]
// 		}
// 		metaCond["meta_key"] = meta
// 		metaConds = append(metaConds, metaCond)
// 	}

// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "ID",
// 		Query:  subQuery.Where(metaConds),
// 		Neg:    neg,
// 	})
// }

// if in.Meta != "" { // 格式： "meta_key=meta_value"
// 	searchMeta(in.Meta)
// } else if in.MetaAnd != nil && len(in.MetaAnd) > 0 {
// 	for _, meta := range sqrlx.UniqueString(in.MetaAnd) {
// 		searchMeta(meta)
// 	}
// } else if in.MetaIn != nil && len(in.MetaIn) > 0 {
// 	searchMeta(sqrlx.UniqueString(in.MetaIn)...)
// } else if in.MetaNotIn != nil && len(in.MetaNotIn) > 0 {
// 	searchMeta(append([]string{"is not in"}, sqrlx.UniqueString(in.MetaNotIn)...)...)
// }

// if in.Name != "" {
// 	q = q.Where(sq.Eq{"post_name": in.Name})
// } else if in.NameIn != nil && len(in.NameIn) > 0 {
// 	q = q.Where(sq.Eq{"post_name": sqrlx.UniqueString(in.NameIn)})
// } else if in.NameNotIn != nil && len(in.NameNotIn) > 0 {
// 	q = q.Where(sq.NotEq{"post_name": sqrlx.UniqueString(in.NameNotIn)})
// }

// if in.Parent > 0 {
// 	q = q.Where(sq.Eq{"post_parent_id": in.Parent})
// } else if in.ParentIn != nil && len(in.ParentIn) > 0 {
// 	q = q.Where(sq.Eq{"post_parent_id": sqrlx.UniqueInt64(in.ParentIn)})
// } else if in.ParentNotIn != nil && len(in.ParentNotIn) > 0 {
// 	q = q.Where(sq.NotEq{"post_parent_id": sqrlx.UniqueInt64(in.ParentNotIn)})
// }

// if in.Post > 0 {
// 	q = q.Where(sq.Eq{"ID": in.Post})
// } else if in.PostIn != nil && len(in.PostIn) > 0 {
// 	q = q.Where(sq.Eq{"ID": sqrlx.UniqueInt64(in.PostIn)})
// } else if in.PostNotIn != nil && len(in.PostNotIn) > 0 {
// 	q = q.Where(sq.NotEq{"ID": sqrlx.UniqueInt64(in.PostNotIn)})
// }

// if in.TagId > 0 {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "ID",
// 		Query: termsSubQuery.Where(sq.Eq{
// 			"tt.taxonomy": string(enumx.TaxonomyPostTag),
// 			"t.term_id":   in.TagId,
// 		}),
// 	})
// } else if in.TagIdAnd != nil && len(in.TagIdAnd) > 0 {
// 	for _, tagId := range sqrlx.UniqueInt64(in.TagIdAnd) {
// 		q = q.Where(sqrlx.InSubquery{
// 			Column: "ID",
// 			Query: termsSubQuery.Where(sq.Eq{
// 				"tt.taxonomy": string(enumx.TaxonomyPostTag),
// 				"t.term_id":   tagId,
// 			}),
// 		})
// 	}
// } else if in.TagIdIn != nil && len(in.TagIdIn) > 0 {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "ID",
// 		Query: termsSubQuery.Where(sq.Eq{
// 			"tt.taxonomy": string(enumx.TaxonomyPostTag),
// 			"t.term_id":   sqrlx.UniqueInt64(in.TagIdIn),
// 		}),
// 	})
// } else if in.TagIdNotIn != nil && len(in.TagIdNotIn) > 0 {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "ID",
// 		Query: termsSubQuery.Where(sq.Eq{
// 			"tt.taxonomy": string(enumx.TaxonomyPostTag),
// 			"t.term_id":   sqrlx.UniqueInt64(in.TagIdNotIn),
// 		}),
// 		Neg: true,
// 	})
// }

// if in.TagName != "" {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "ID",
// 		Query: termsSubQuery.Where(sq.Eq{
// 			"tt.`taxonomy`": string(enumx.TaxonomyPostTag),
// 			"t.`slug`":      in.TagName,
// 		}),
// 	})
// } else if in.TagNameAnd != nil && len(in.TagNameAnd) > 0 {
// 	for _, tagName := range sqrlx.UniqueString(in.TagNameAnd) {
// 		q = q.Where(sqrlx.InSubquery{
// 			Column: "ID",
// 			Query: termsSubQuery.Where(sq.Eq{
// 				"tt.`taxonomy`": string(enumx.TaxonomyPostTag),
// 				"t.`slug`":      tagName,
// 			}),
// 		})
// 	}
// } else if in.TagNameIn != nil && len(in.TagNameIn) > 0 {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "ID",
// 		Query: termsSubQuery.Where(sq.Eq{
// 			"tt.`taxonomy`": string(enumx.TaxonomyPostTag),
// 			"t.`slug`":      sqrlx.UniqueString(in.TagNameIn),
// 		}),
// 	})
// } else if in.TagNameNotIn != nil && len(in.TagNameNotIn) > 0 {
// 	q = q.Where(sqrlx.InSubquery{
// 		Column: "ID",
// 		Query: termsSubQuery.Where(sq.Eq{
// 			"tt.`taxonomy`": string(enumx.TaxonomyPostTag),
// 			"t.`slug`":      sqrlx.UniqueString(in.TagNameNotIn),
// 		}),
// 		Neg: true,
// 	})
// }

// if in.Query != "" { // 格式： 2个字符以上，','切分多个
// 	var pred string
// 	var args []any
// 	for _, word := range regexpQueryDelimiter.Split(in.Query, -1) {
// 		if len(word) > 2 {
// 			pred += "post_name LIKE ? OR post_title LIKE ? OR "

// 			word = "%" + word + "%"
// 			args = append(args, word, word)
// 		}
// 	}

// 	if pred != "" {
// 		q = q.Where("("+pred[:len(pred)-4]+")", args...)
// 	}
// }

// if in.Day > 0 {
// 	q = q.Where(sq.Eq{"DAYOFMONTH(post_date)": in.Day}) // 返回日期在本月的第几天，范围为1到31
// }

// if in.Month > 0 {
// 	q = q.Where(sq.Eq{"MONTH(post_date)": in.Month}) // 返回指定日期的月份，1月至12月的范围为1到12
// }

// if in.Year > 0 {
// 	q = q.Where(sq.Eq{"YEAR(post_date)": in.Year}) // 返回指定日期的年份，在1000到9999之间
// }

// if in.AfterDate != "" {
// 	q = q.Where("post_date > ?", in.AfterDate)
// }

// if in.After > 0 {
// 	pred := "`ID`"
// 	if in.DefaultOrderAscending {
// 		pred += " > "
// 		q = q.OrderBy("`ID` ASC")
// 	} else {
// 		pred += " < "
// 		q = q.OrderBy("`ID` DESC")
// 	}
// 	pred += "?"

// 	q = q.Where(pred, in.After)
// }

// if in.OrderBy != nil && len(in.OrderBy) > 0 {
// 	for _, orderBy := range sqrlx.UniqueString(in.OrderBy) {
// 		q = q.OrderBy(orderBy)
// 	}
// }

// if in.Limit == 0 {
// 	in.Limit = l.svcCtx.Config.Query.DefaultAmount
// }

// if in.Limit > 0 {
// 	q = q.Limit(uint64(in.Limit) + 1)
// }

// ids, err := l.svcCtx.BlogPostModel.QueryIds(l.ctx, q)
// if err != nil {
// 	return nil, err
// }
// return ids, nil
// }

// func (l *PostListLogic) QueryList(objectIds []int64, nextId int64) (*blog.ObjectListResponse, error) {
// ids := sqrlx.UniqueInt64(objectIds)

// q := l.svcCtx.BlogPostModel.RowBuilder("", "")
// q = q.Where(sq.Eq{"ID": ids})
// postList, err := l.svcCtx.BlogPostModel.QueryList(l.ctx, q)
// if err != nil {
// 	return nil, err
// }

// q := l.svcCtx.BlogPostMetaModel.RowBuilder("")
// q = q.Where(sq.Eq{"post_id": ids})
// metaList, err := l.svcCtx.BlogPostMetaModel.QueryList(l.ctx, q)

// posts := make([]*blog.PostDetailResponse, 0, len(ids))
// for _, post := range postList {
// 	posts = append(posts, &blog.PostDetailResponse{
// 		Id:     post.ID,
// 		Status: post.PostStatus,
// 		Slug:   post.PostName,
// 		Uri:    post.Guid,
// 	})
// }

// 	return &blog.ObjectListResponse{
// 		NextId: nextId,
// 		Post:   posts,
// 	}, nil
// }
